package com.lyf.boot.auth;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lyf.boot.base.system.entity.SysClient;
import com.lyf.boot.base.user.dao.BaseUserDao;
import com.lyf.boot.base.user.entity.User;
import com.lyf.boot.constant.Constant;
import com.lyf.boot.core.model.LoginUser;
import com.lyf.boot.core.model.LoginVo;
import com.lyf.boot.core.service.IAuthStrategy;
import com.lyf.boot.exception.ServiceException;
import com.lyf.boot.modules.index.entity.dto.LoginDto;
import com.lyf.boot.utils.AuthUtil;
import com.lyf.boot.utils.JsonUtil;
import com.lyf.boot.utils.ValidatorUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @author Luyufan
 * @date 2024/1/11 09:17
 **/
@Slf4j
@Service("password" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class PasswordAuthStrategy implements IAuthStrategy {

    private final BaseUserDao baseUserDao;

    @Override
    public LoginVo login(String body, SysClient client) {
        LoginDto loginDto = JsonUtil.parseObject(body, LoginDto.class);
        if(null == loginDto){
            throw new ServiceException("登录参数异常");
        }
        ValidatorUtil.validate(loginDto);
        String username = loginDto.getUsername();
        User user = baseUserDao.selectOne(Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, username));
        Assert.notNull(user, "账号不存在");
        Assert.state(BCrypt.checkpw(loginDto.getPassword(), user.getPassword()), "账号或密码不正确");
        Assert.equals(Constant.ONE, user.getStatus(), "账号已被冻结");
        Long userId = user.getUserId();
        LoginUser loginUser = new LoginUser().setUserId(userId).setUsername(username)
                .setRealName(user.getRealName())
                .setUsername(username).setNickName(user.getNickName());
        SaLoginModel model = new SaLoginModel();
        model.setDevice(client.getDeviceType());
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        model.setExtra(AuthUtil.CLIENT_KEY, client.getClientCode());
        AuthUtil.login(loginUser, model);
        return new LoginVo()
        .setAccessToken(StpUtil.getTokenValue())
        .setExpireIn(StpUtil.getTokenTimeout())
        .setClientCode(client.getClientCode())
        .setUserId(AuthUtil.getUserId());
    }
}
